package com.ly.demo.vo;

import cn.hutool.core.convert.Convert;
import lombok.Data;

import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Stack;

@Data
public class TestBodyBySet {
    private HashSet hashSet;

    public static double evaluate(String expression) {
        Stack<Double> values = new Stack<>();
        Stack<Character> operators = new Stack<>();
        expression = expression.replace(" ", "");
        for (int i = 0; i < expression.length(); i++) {
            char ch = expression.charAt(i);
            // 处理数字
            if (Character.isDigit(ch)) {
                StringBuilder sb = new StringBuilder();
                while (i < expression.length() && (Character.isDigit(expression.charAt(i)) || expression.charAt(i) == '.')) {
                    sb.append(expression.charAt(i++));
                }
                values.push(Double.parseDouble(sb.toString()));
                i--; // 因为外层循环会再增加 i，所以这里需要减少一次
            }
            // 处理左括号
            else if (ch == '(') {
                operators.push(ch);
            }
            // 处理右括号
            else if (ch == ')') {
                while (operators.peek() != '(') {
                    values.push(applyOperator(operators.pop(), values.pop(), values.pop()));
                }
                operators.pop(); // 弹出 '('
            }else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
                while (!operators.isEmpty() && hasPrecedence(ch, operators.peek())) {
                    values.push(applyOperator(operators.pop(), values.pop(), values.pop()));
                }
                operators.push(ch);
            }
        }

        // 计算剩余的运算符
        while (!operators.isEmpty()) {
            values.push(applyOperator(operators.pop(), values.pop(), values.pop()));
        }

        return values.pop();
    }

    private static boolean hasPrecedence(char op1, char op2) {
        if (op2 == '(' || op2 == ')') {
            return false;
        }
        return (op1 != '*' && op1 != '/') || (op2 != '+' && op2 != '-');
    }

    private static double applyOperator(char op, double b, double a) {
        switch (op) {
            case '+': return a + b;
            case '-': return a - b;
            case '*': return a * b;
            case '/':
                if (b == 0) throw new ArithmeticException("Cannot divide by zero");
                return a / b;
        }
        throw new IllegalArgumentException("Invalid operator: " + op);
    }

}
